package com.kamisama.utopia.service;

import com.kamisama.utopia.command.Command;
import com.kamisama.utopia.command.Action;
import com.kamisama.utopia.command.Trigger;
import com.kamisama.utopia.dto.CommandDto;

import java.util.Arrays;

import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

@Service
public class CommandService {

    @Autowired
    private KieContainer kContainer;

    @Autowired
    private CharacterService characterService;

    public CommandDto execute(CommandDto commandDto) {
        Command command = Command.builder().build();
        boolean decomposesCommandSuccess = decomposesCommand(command, commandDto.getCommand());
        if (decomposesCommandSuccess) {
            if (!command.getAction().equals(Action.LOGIN.getAction()) && !command.getAction().equals(Action.REGIST.getAction()) && StringUtils.isEmpty(commandDto.getCharacterId())) {
                commandDto.setRespond("尚未登录，请使用命令 #登录");
                return commandDto;
            }
            fireRules(command, commandDto);
            save();
            return commandDto;
        } else {
            return null;
        }
    }

    private boolean decomposesCommand(Command command, String orginCommand) {
        String triggerWord = orginCommand.substring(0, 1);
        String actionWord = orginCommand.substring(1);
        if (Arrays.stream(Trigger.values()).map(Trigger::getTrigger)
                .anyMatch(t -> t.equals(triggerWord)) && !StringUtils.isEmpty(actionWord)) {
            command.setTrigger(triggerWord);
            Arrays.stream(Action.values()).map(Action::getAction).forEach(a -> {
                if (actionWord.contains(a)) {
                    command.setAction(a);
                }
            });
            if (StringUtils.isEmpty(command.getAction())) {
                return false;
            } else {
                String target = actionWord.replace(command.getAction(), "");
                if (!StringUtils.isEmpty(target)) {
                    command.setTarget(target);
                }
            }
            return true;
        } else {
            return false;
        }
    }

    private void save() {

    }

    private void fireRules(Command command, CommandDto commandDto) {
        KieSession kSession = kContainer.newKieSession("command-rules");

        kSession.setGlobal("characterService", characterService);
        kSession.insert(command);
        kSession.insert(commandDto);

        kSession.fireAllRules();
        kSession.dispose();
    }
}
